tree grammar iLPMEDtocLPMED;

options {
	tokenVocab=LPMEDLexer; // use the vocabulary from the parser
	ASTLabelType=CommonTree; // what kind of trees are we walking?
	language = CSharp2;
	output = AST;
}

@namespace { Core.ANTLRGrammars }

program[string ModuleName]
scope
{
	string DDname;
}
:
	^(CPROGRAM varDecList* ^(CSTATEMENT stmt*)) 
		-> ^(CPROGRAM ^(CDEVICE ID[$ModuleName]) varDecList* ^(CSTATEMENT stmt*))
;


varDecList : ^(CTYPE TYPE ID+);


stmt
options { backtrack=false;}
:
			assign
		|	ifStmt
		|	^(CWHILE expr blockStmt)
		|	^(CFOR assign expr assign blockStmt)
		|	deviceFuncID
		|	blockStmt
		|	CTERMINATEALL
		|	functionCall
;

blockStmt : ^(CSTATEMENT stmt*)
;

assign options{backtrack=true;}	
:	
	^(CASSIGN ID expr)
;

ifStmt
options { backtrack=true; }
: 
	^(CIFTE expr a=blockStmt b=blockStmt?)
;

expr options{backtrack=true;}
:	
^(OpOr expr expr)
|^(OpAnd expr expr)
|^(OpLogicalB expr expr)
|^(OpLogicalA expr expr)
|^(OpAddSub expr expr)
|^(OpDivMul expr expr)
|^(OpNegation expr)
|^(OpUnar expr)
|'(' expr ')'
|atom
;

atom
options
{
	backtrack=true;
}	
 :
 ID
 | ^(v = CFLOAT FLOAT)
 | ^(v = CINT INT)
 | ^(v = CBOOL DBOOL)
 | ^(OBJECTNAME ID) ^(NODES ID*) ^(MEMBERNAME ID)
 | ^(CGETSTATE ^(OBJECTNAME ID) ^(NODES ID*))
;

qualifiedName	:
	^(OBJECTNAME ID) ^(NODES ID*) ^(MEMBERNAME ID)
;


deviceFuncID 	
:       
        	^(CCALL ^(CSYNCCALL qualifiedName))			
	|	^(CCALL ^(CASYNCCALL qualifiedName))
	|	^(CCALL ^(CENDTHECALL qualifiedName))
	|	^(CCALL ^(CWAITTHECALL qualifiedName))
	|	^(CCALL ^(CWAITANYCALL qualifiedName))
;

functionCall
: 
			^(CASYNCFUNCCALL ID parameter*)
		| 	^(CWAITFUNCFINISH ID parameter*)
		|	^(CSYNCFUNCCALL ID parameter*)
;


parameter	: 
	^(PARAM parameterValue)
;

parameterValue	:
			ID		//variable
		| 	INT		//number
		|	qualifiedName	//named state
;
